import { Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { Cron, CronExpression } from "@nestjs/schedule";
import { CasinoUnifiedRoundService } from "./casino-unified-round.service";
import { CasinoBetService } from "./casino-bet.service";
import { CasinoSettlementService } from "./casino-settlement.service";
import { CasinoCacheService } from "./casino-cache.service";
import { GameType } from "../entities";

@Injectable()
export class CasinoMonitoringService implements OnModuleInit {
  private readonly logger = new Logger(CasinoMonitoringService.name);

  // 性能指标
  private performanceMetrics = {
    totalRequests: 0,
    successfulRequests: 0,
    failedRequests: 0,
    averageResponseTime: 0,
    responseTimes: [] as number[],
    lastUpdate: Date.now(),
  };

  // 系统状态
  private systemStatus = {
    isHealthy: true,
    lastHealthCheck: Date.now(),
    errors: [] as string[],
    warnings: [] as string[],
  };

  constructor(
    private readonly roundService: CasinoUnifiedRoundService,
    private readonly betService: CasinoBetService,
    private readonly settlementService: CasinoSettlementService,
    private readonly cacheService: CasinoCacheService
  ) {}

  onModuleInit() {
    this.logger.log("📊 娱乐城监控服务启动成功！");
    this.logger.log("🔍 监控功能已启用：");
    this.logger.log("   • 性能监控 (请求统计、响应时间、成功率)");
    this.logger.log("   • 系统健康检查 (每小时执行)");
    this.logger.log("   • 数据库状态监控");
    this.logger.log("   • 缓存状态监控");
    this.logger.log("   • 游戏状态监控");
    this.logger.log("   • 性能指标监控");
    this.logger.log("🚨 告警系统已启用，支持 info/warning/error 级别");
  }

  // ==================== 性能监控 ====================

  /**
   * 记录请求性能
   */
  recordRequest(duration: number, success: boolean): void {
    this.performanceMetrics.totalRequests++;

    if (success) {
      this.performanceMetrics.successfulRequests++;
    } else {
      this.performanceMetrics.failedRequests++;
    }

    // 记录响应时间
    this.performanceMetrics.responseTimes.push(duration);

    // 保持最近100个响应时间
    if (this.performanceMetrics.responseTimes.length > 100) {
      this.performanceMetrics.responseTimes.shift();
    }

    // 计算平均响应时间
    this.performanceMetrics.averageResponseTime =
      this.performanceMetrics.responseTimes.reduce((a, b) => a + b, 0) /
      this.performanceMetrics.responseTimes.length;

    this.performanceMetrics.lastUpdate = Date.now();
  }

  /**
   * 获取性能指标
   */
  getPerformanceMetrics() {
    const successRate =
      this.performanceMetrics.totalRequests > 0
        ? (this.performanceMetrics.successfulRequests /
            this.performanceMetrics.totalRequests) *
          100
        : 0;

    return {
      ...this.performanceMetrics,
      successRate: Math.round(successRate * 100) / 100,
      errorRate: Math.round((100 - successRate) * 100) / 100,
    };
  }

  // ==================== 系统健康检查 ====================

  /**
   * 每小时执行系统健康检查
   */
  @Cron(CronExpression.EVERY_HOUR)
  async performHealthCheck(): Promise<void> {
    try {
      this.logger.log("🏥 开始系统健康检查...");

      const healthResults = await Promise.allSettled([
        this.checkDatabaseHealth(),
        this.checkCacheHealth(),
        this.checkGameStateHealth(),
        this.checkPerformanceHealth(),
      ]);

      // 分析健康检查结果
      const errors: string[] = [];
      const warnings: string[] = [];

      healthResults.forEach((result, index) => {
        if (result.status === "rejected") {
          const checkNames = ["数据库", "缓存", "游戏状态", "性能"];
          errors.push(`${checkNames[index]}健康检查失败: ${result.reason}`);
        }
      });

      // 更新系统状态
      this.systemStatus.isHealthy = errors.length === 0;
      this.systemStatus.errors = errors;
      this.systemStatus.warnings = warnings;
      this.systemStatus.lastHealthCheck = Date.now();

      if (this.systemStatus.isHealthy) {
        this.logger.log("✅ 系统健康检查通过");
      } else {
        this.logger.warn(`⚠️ 系统健康检查发现问题: ${errors.join(", ")}`);
      }
    } catch (error: any) {
      this.logger.error("❌ 系统健康检查失败:", error?.message || error);
      this.systemStatus.isHealthy = false;
      this.systemStatus.errors.push(
        `健康检查执行失败: ${error?.message || error}`
      );
    }
  }

  /**
   * 检查数据库健康状态
   */
  private async checkDatabaseHealth(): Promise<boolean> {
    try {
      // 检查各游戏类型的期数状态
      const gameTypes = [
        GameType.DICE,
        GameType.CHIBI,
        GameType.ROCK_PAPER_SCISSORS,
      ];

      for (const gameType of gameTypes) {
        const currentRound = await this.roundService.getCurrentRound(gameType);
        if (!currentRound) {
          throw new Error(`${this.getGameTypeName(gameType)}没有当前期数`);
        }
      }

      return true;
    } catch (error: any) {
      this.logger.error("数据库健康检查失败:", error?.message || error);
      throw error;
    }
  }

  /**
   * 检查缓存健康状态
   */
  private async checkCacheHealth(): Promise<boolean> {
    try {
      const cacheStats = await this.cacheService.getCacheStats();

      // 检查缓存键数量
      if (cacheStats.totalKeys > 10000) {
        this.logger.warn("缓存键数量过多，可能存在内存泄漏");
      }

      // 检查内存使用
      if (
        cacheStats.memoryUsage.includes("MB") ||
        cacheStats.memoryUsage.includes("GB")
      ) {
        const memoryValue = parseFloat(cacheStats.memoryUsage);
        if (memoryValue > 100) {
          // 超过100MB
          this.logger.warn("缓存内存使用过高");
        }
      }

      return true;
    } catch (error: any) {
      this.logger.error("缓存健康检查失败:", error?.message || error);
      throw error;
    }
  }

  /**
   * 检查游戏状态健康状态
   */
  private async checkGameStateHealth(): Promise<boolean> {
    try {
      const gameTypes = [
        GameType.DICE,
        GameType.CHIBI,
        GameType.ROCK_PAPER_SCISSORS,
      ];

      for (const gameType of gameTypes) {
        const stats = await this.roundService.getRoundStatistics(gameType);

        // 检查是否有异常数据
        if (stats.totalRounds < 0 || stats.activeRounds < 0) {
          throw new Error(`${this.getGameTypeName(gameType)}统计数据异常`);
        }
      }

      return true;
    } catch (error: any) {
      this.logger.error("游戏状态健康检查失败:", error?.message || error);
      throw error;
    }
  }

  /**
   * 检查性能健康状态
   */
  private async checkPerformanceHealth(): Promise<boolean> {
    try {
      const metrics = this.getPerformanceMetrics();

      // 检查成功率
      if (metrics.successRate < 95) {
        this.logger.warn(`请求成功率过低: ${metrics.successRate}%`);
      }

      // 检查平均响应时间
      if (metrics.averageResponseTime > 1000) {
        // 超过1秒
        this.logger.warn(`平均响应时间过长: ${metrics.averageResponseTime}ms`);
      }

      // 检查错误率
      if (metrics.errorRate > 5) {
        this.logger.warn(`错误率过高: ${metrics.errorRate}%`);
      }

      return true;
    } catch (error: any) {
      this.logger.error("性能健康检查失败:", error?.message || error);
      throw error;
    }
  }

  // ==================== 系统状态查询 ====================

  /**
   * 获取系统状态
   */
  getSystemStatus() {
    return {
      ...this.systemStatus,
      uptime: Date.now() - this.systemStatus.lastHealthCheck,
      performance: this.getPerformanceMetrics(),
    };
  }

  /**
   * 获取系统概览
   */
  async getSystemOverview() {
    try {
      const gameTypes = [
        GameType.DICE,
        GameType.CHIBI,
        GameType.ROCK_PAPER_SCISSORS,
      ];
      const gameStats = [];

      for (const gameType of gameTypes) {
        const stats = await this.roundService.getRoundStatistics(gameType);
        gameStats.push({
          gameType: this.getGameTypeName(gameType),
          totalRounds: stats.totalRounds,
          activeRounds: stats.activeRounds,
          totalBets: stats.totalBets,
        });
      }

      const cacheStats = await this.cacheService.getCacheStats();
      const performanceMetrics = this.getPerformanceMetrics();

      return {
        timestamp: new Date().toISOString(),
        system: {
          isHealthy: this.systemStatus.isHealthy,
          lastHealthCheck: this.systemStatus.lastHealthCheck,
          uptime: Date.now() - this.systemStatus.lastHealthCheck,
        },
        games: gameStats,
        cache: cacheStats,
        performance: performanceMetrics,
        errors: this.systemStatus.errors,
        warnings: this.systemStatus.warnings,
      };
    } catch (error: any) {
      this.logger.error("获取系统概览失败:", error?.message || error);
      throw error;
    }
  }

  // ==================== 告警机制 ====================

  /**
   * 发送系统告警
   */
  private sendAlert(
    level: "info" | "warning" | "error",
    message: string
  ): void {
    const timestamp = new Date().toISOString();
    const alert = { level, message, timestamp };

    switch (level) {
      case "info":
        this.logger.log(`ℹ️ ${message}`);
        break;
      case "warning":
        this.logger.warn(`⚠️ ${message}`);
        break;
      case "error":
        this.logger.error(`🚨 ${message}`);
        break;
    }

    // TODO: 这里可以集成实际的告警系统（邮件、短信、钉钉等）
    // this.alertService.send(alert);
  }

  /**
   * 检查是否需要发送告警
   */
  private checkAlertConditions(): void {
    const metrics = this.getPerformanceMetrics();

    // 成功率告警
    if (metrics.successRate < 90) {
      this.sendAlert("error", `系统成功率过低: ${metrics.successRate}%`);
    } else if (metrics.successRate < 95) {
      this.sendAlert("warning", `系统成功率偏低: ${metrics.successRate}%`);
    }

    // 响应时间告警
    if (metrics.averageResponseTime > 2000) {
      this.sendAlert(
        "error",
        `系统响应时间过长: ${metrics.averageResponseTime}ms`
      );
    } else if (metrics.averageResponseTime > 1000) {
      this.sendAlert(
        "warning",
        `系统响应时间偏长: ${metrics.averageResponseTime}ms`
      );
    }

    // 错误率告警
    if (metrics.errorRate > 10) {
      this.sendAlert("error", `系统错误率过高: ${metrics.errorRate}%`);
    } else if (metrics.errorRate > 5) {
      this.sendAlert("warning", `系统错误率偏高: ${metrics.errorRate}%`);
    }
  }

  // ==================== 工具方法 ====================

  /**
   * 获取游戏类型名称
   */
  private getGameTypeName(gameType: GameType): string {
    const names = {
      [GameType.DICE]: "大小玩法",
      [GameType.CHIBI]: "赤壁玩法",
      [GameType.ROCK_PAPER_SCISSORS]: "美人计玩法",
    };
    return names[gameType] || "未知";
  }

  /**
   * 重置性能指标
   */
  resetPerformanceMetrics(): void {
    this.performanceMetrics = {
      totalRequests: 0,
      successfulRequests: 0,
      failedRequests: 0,
      averageResponseTime: 0,
      responseTimes: [],
      lastUpdate: Date.now(),
    };
    this.logger.log("性能指标已重置");
  }

  /**
   * 清理系统状态
   */
  clearSystemStatus(): void {
    this.systemStatus.errors = [];
    this.systemStatus.warnings = [];
    this.logger.log("系统状态已清理");
  }
}
